// MongoDB 初始化脚本（集合与索引创建）
// 使用方式（在命令行中运行）：
//   mongosh --file db/mongo_init.js
// 或：
//   mongosh < db\mongo_init.js
// 数据库名称可按需修改为环境实际名称。

const DB_NAME = 'fames';
const DB = db.getSiblingDB(DB_NAME);

function ensureCollection(name, jsonSchema) {
  const exists = DB.getCollectionNames().includes(name);
  if (!exists) {
    DB.createCollection(name, {
      validator: { $jsonSchema: jsonSchema },
      validationLevel: 'moderate',
      validationAction: 'error'
    });
    print(`Created collection: ${name}`);
  } else {
    // 更新校验规则（如集合已存在）
    DB.runCommand({
      collMod: name,
      validator: { $jsonSchema: jsonSchema },
      validationLevel: 'moderate',
      validationAction: 'error'
    });
    print(`Updated validator for collection: ${name}`);
  }
}

// 1) attachments（附件集合）
ensureCollection('attachments', {
  bsonType: 'object',
  required: ['owner_type', 'owner_id', 'files'],
  properties: {
    owner_type: { enum: ['activity', 'event'] },
    owner_id: { bsonType: 'string' },
    files: {
      bsonType: 'array',
      minItems: 1,
      items: {
        bsonType: 'object',
        required: ['filename', 'content_type', 'size_bytes', 'storage_url', 'uploaded_at', 'uploader'],
        properties: {
          filename: { bsonType: 'string' },
          content_type: { bsonType: 'string' },
          size_bytes: { bsonType: 'long' },
          storage_url: { bsonType: 'string' },
          md5: { bsonType: 'string' },
          uploaded_at: { bsonType: 'date' },
          uploader: { bsonType: 'string' }
        }
      }
    },
    tags: { bsonType: 'array', items: { bsonType: 'string' } },
    remark: { bsonType: 'string' }
  }
});
DB.attachments.createIndex({ owner_type: 1, owner_id: 1 });

// 2) reports（评估报告集合）
ensureCollection('reports', {
  bsonType: 'object',
  required: ['activity_id', 'evaluation_id', 'template_version_code', 'docx', 'sections', 'status', 'audit'],
  properties: {
    activity_id: { bsonType: 'string' },
    evaluation_id: { bsonType: 'string' },
    template_version_code: { bsonType: 'string' },
    docx: {
      bsonType: 'object',
      required: ['file_url', 'generated_at', 'generated_by'],
      properties: {
        file_url: { bsonType: 'string' },
        generated_at: { bsonType: 'date' },
        generated_by: { bsonType: 'string' }
      }
    },
    pdf: {
      bsonType: 'object',
      properties: {
        file_url: { bsonType: 'string' },
        generated_at: { bsonType: 'date' }
      }
    },
    sections: {
      bsonType: 'array',
      minItems: 1,
      items: {
        bsonType: 'object',
        required: ['section_no', 'section_name', 'level', 'status', 'content'],
        properties: {
          section_no: { bsonType: 'string' },
          section_name: { bsonType: 'string' },
          level: { bsonType: 'int' },
          style: { bsonType: 'string' },
          required: { bsonType: 'bool' },
          status: { enum: ['draft', 'reviewed', 'final'] },
          binding: {
            bsonType: 'object',
            properties: {
              activity_fields: { bsonType: 'array', items: { bsonType: 'string' } },
              indicator_item_ids: { bsonType: 'array', items: { bsonType: 'string' } },
              indicator_theme_ids: { bsonType: 'array', items: { bsonType: 'string' } },
              event_ids: { bsonType: 'array', items: { bsonType: 'string' } },
              event_filters: {
                bsonType: 'object',
                properties: {
                  types: { bsonType: 'array', items: { bsonType: 'string' } },
                  date_range: {
                    bsonType: 'object',
                    properties: {
                      start: { bsonType: 'date' },
                      end: { bsonType: 'date' }
                    }
                  },
                  status: { bsonType: 'array', items: { bsonType: 'string' } }
                }
              },
              computed_metrics: {
                bsonType: 'object',
                properties: {
                  score_total: { bsonType: 'double' },
                  deductions: {
                    bsonType: 'array',
                    items: {
                      bsonType: 'object',
                      required: ['item_id', 'value'],
                      properties: {
                        item_id: { bsonType: 'string' },
                        value: { bsonType: 'double' }
                      }
                    }
                  },
                  veto_hit: { bsonType: 'bool' }
                }
              }
            }
          },
          content: {
            bsonType: 'object',
            properties: {
              raw_text: { bsonType: 'string' },
              edited_text: { bsonType: 'string' },
              tables: {
                bsonType: 'array',
                items: {
                  bsonType: 'object',
                  required: ['table_type', 'columns', 'rows', 'source'],
                  properties: {
                    table_type: { bsonType: 'string' },
                    columns: { bsonType: 'array', items: { bsonType: 'string' } },
                    rows: { bsonType: 'array', items: { bsonType: 'object' } },
                    source: { enum: ['postgres:sql', 'computed', 'manual'] }
                  }
                }
              },
              images: {
                bsonType: 'array',
                items: {
                  bsonType: 'object',
                  required: ['attachment_id'],
                  properties: {
                    attachment_id: { bsonType: 'string' },
                    caption: { bsonType: 'string' },
                    position: { bsonType: 'int' }
                  }
                }
              }
            },
            oneOf: [
              { required: ['raw_text'] },
              { required: ['edited_text'] }
            ]
          },
          sources: {
            bsonType: 'array',
            items: {
              bsonType: 'object',
              required: ['kb_source_id'],
              properties: {
                kb_source_id: { bsonType: 'string' },
                chunk_ids: { bsonType: 'array', items: { bsonType: 'string' } },
                citation_text: { bsonType: 'string' }
              }
            }
          },
          llm: {
            bsonType: 'object',
            properties: {
              model: { bsonType: 'string' },
              prompt: { bsonType: 'string' },
              variables: { bsonType: 'object' },
              temperature: { bsonType: 'double' },
              tokens: {
                bsonType: 'object',
                properties: {
                  input: { bsonType: 'int' },
                  output: { bsonType: 'int' }
                }
              },
              warnings: { bsonType: 'array', items: { bsonType: 'string' } }
            }
          },
          audit: {
            bsonType: 'object',
            required: ['created_at', 'created_by'],
            properties: {
              created_at: { bsonType: 'date' },
              created_by: { bsonType: 'string' },
              updated_at: { bsonType: 'date' },
              updated_by: { bsonType: 'string' }
            }
          }
        }
      }
    },
    status: { enum: ['draft', 'final'] },
    audit: {
      bsonType: 'object',
      required: ['created_at', 'created_by'],
      properties: {
        created_at: { bsonType: 'date' },
        created_by: { bsonType: 'string' },
        updated_at: { bsonType: 'date' },
        updated_by: { bsonType: 'string' }
      }
    }
  }
});
DB.reports.createIndex({ activity_id: 1, evaluation_id: 1 });
DB.reports.createIndex({ template_version_code: 1 });
DB.reports.createIndex({ 'sections.section_no': 1 });

// 3) audit_logs（操作审计）
ensureCollection('audit_logs', {
  bsonType: 'object',
  required: ['actor', 'action', 'target_type', 'target_id', 'occurred_at'],
  properties: {
    actor: { bsonType: 'string' },
    action: { bsonType: 'string' },
    target_type: { bsonType: 'string' },
    target_id: { bsonType: 'string' },
    payload: { bsonType: 'object' },
    occurred_at: { bsonType: 'date' }
  }
});
DB.audit_logs.createIndex({ target_type: 1, target_id: 1, occurred_at: -1 });

// 4) report_template_outline（模板章节骨架）
ensureCollection('report_template_outline', {
  bsonType: 'object',
  required: ['template_version_code', 'outline'],
  properties: {
    template_version_code: { bsonType: 'string' },
    outline: {
      bsonType: 'array',
      minItems: 1,
      items: {
        bsonType: 'object',
        required: ['section_no', 'section_name', 'level', 'style', 'required'],
        properties: {
          section_no: { bsonType: 'string' },
          section_name: { bsonType: 'string' },
          level: { bsonType: 'int' },
          style: { bsonType: 'string' },
          required: { bsonType: 'bool' },
          default_binding: {
            bsonType: 'object',
            properties: {
              data_source: { enum: ['activity', 'events', 'evaluation', 'mix'] },
              indicator_scopes: {
                bsonType: 'object',
                properties: {
                  dimension_ids: { bsonType: 'array', items: { bsonType: 'string' } },
                  theme_ids: { bsonType: 'array', items: { bsonType: 'string' } }
                }
              },
              event_scopes: {
                bsonType: 'object',
                properties: {
                  types: { bsonType: 'array', items: { bsonType: 'string' } },
                  status: { bsonType: 'array', items: { bsonType: 'string' } }
                }
              }
            }
          }
        }
      }
    }
  }
});
DB.report_template_outline.createIndex({ template_version_code: 1 }, { unique: true });

// 5) kb_sources（知识库源）
ensureCollection('kb_sources', {
  bsonType: 'object',
  required: ['title', 'type'],
  properties: {
    title: { bsonType: 'string' },
    type: { enum: ['docx', 'pdf', 'web', 'md', 'txt'] },
    file_path: { bsonType: 'string' },
    url: { bsonType: 'string' },
    template_version_code: { bsonType: 'string' },
    index_ref: { bsonType: 'string' },
    metadata: { bsonType: 'object' }
  },
  oneOf: [
    { required: ['file_path'] },
    { required: ['url'] }
  ]
});
DB.kb_sources.createIndex({ title: 'text' });

// 6) kb_doc_chunks（知识库文档片段）
ensureCollection('kb_doc_chunks', {
  bsonType: 'object',
  required: ['kb_source_id', 'content', 'order_index'],
  properties: {
    kb_source_id: { bsonType: 'string' },
    section_hint: { bsonType: 'string' },
    content: { bsonType: 'string' },
    embedding_ref: { bsonType: 'string' },
    order_index: { bsonType: 'int' }
  }
});
DB.kb_doc_chunks.createIndex({ kb_source_id: 1, order_index: 1 });

// 7) section_generation_runs（章节生成审计）
ensureCollection('section_generation_runs', {
  bsonType: 'object',
  required: ['report_id', 'section_no', 'input_snapshot', 'prompt', 'llm_params', 'output_text', 'metrics', 'status', 'created_at'],
  properties: {
    report_id: { bsonType: 'string' },
    section_no: { bsonType: 'string' },
    input_snapshot: { bsonType: 'object' },
    prompt: { bsonType: 'string' },
    llm_params: {
      bsonType: 'object',
      properties: {
        model: { bsonType: 'string' },
        temperature: { bsonType: 'double' },
        top_p: { bsonType: 'double' }
      }
    },
    output_text: { bsonType: 'string' },
    metrics: {
      bsonType: 'object',
      properties: {
        tokens_in: { bsonType: 'int' },
        tokens_out: { bsonType: 'int' },
        duration_ms: { bsonType: 'int' }
      }
    },
    status: { enum: ['success', 'failed'] },
    error: { bsonType: 'string' },
    created_at: { bsonType: 'date' },
    created_by: { bsonType: 'string' }
  }
});
DB.section_generation_runs.createIndex({ report_id: 1, section_no: 1, created_at: -1 });

print('Mongo collections and indexes ensured for DB: ' + DB_NAME);